﻿//-------------------------------------
// WBFSSync - WBFSSync.exe
//
// Copyright 2009 Caian (ÔmΣga Frøst) <frost.omega@hotmail.com>
//
// WBFSSync is Licensed under the terms of the Microsoft Reciprocal License (Ms-RL)
//
// CDDrive.cs:
//
// Implementação da interface que guarda informações sobre dispositivos de armazenagem conectados ao computador
// específica para Drives de CDRom que podem conter um disco de Wii para ser ripado
//
//-------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace WBFSSync
{
    public class CDDrive : IDrive
    {
        public static PartitionSelection DiscBuildMode = PartitionSelection.OnlyGamePartition;

        //--------------------------

        public DriveInfo _Drive = null;
        public DriveFlags _Flags = DriveFlags.Unknown;

        long transfer = 0;
        int numoperations = 0;

        public Boolean _WiiDiscInserted = false;

        public string _Code = "";
        public string _Name = "";
        public long _Size = 0;
        public long _WBFSSize = 0;
        public byte[] _WiiSectorUsageTable = null;

        public string Name { get { try { return _Drive.Name.ToUpper(); } catch { return "?"; } } }
        public DriveFlags Flags { get { return _Flags; } }
        public string Label { get { try { return _Drive.VolumeLabel; } catch { return _Code.Length == 0 ? "" : (_Code + " - " + _Name); } } }
        public bool Ready { get { try { return _Drive.IsReady || _WiiDiscInserted; } catch { return _WiiDiscInserted; } } }

        public long Size { get { try { return _Drive.TotalSize; } catch { return -1; } } }
        public long FreeSpace { get { try { return _Drive.AvailableFreeSpace; } catch { return -1; } } }
        public long UsedSpace { get { try { return _Drive.TotalSize - _Drive.TotalFreeSpace; } catch { return -1; } } }
        public long ReservedSpace { get { return transfer; } set { transfer = Math.Max(value, 0); } }

        public bool Is(DriveFlags flag) { return (_Flags & flag) != DriveFlags.Unknown; }

        public Int32 ActiveOperations { get { return numoperations; } set { numoperations = value; } }

        public int Open(Char d)
        {
            return -1;
        }

        public void Close()
        {
            _WiiDiscInserted = false;
            _Code = "";
            _Name = "";
            _Size = 0;
            _WBFSSize = 0;
            _WiiSectorUsageTable = null;
        }

        public void Refresh()
        {
            _WiiDiscInserted = false;
            _Code = "";
            _Name = "";
            _Size = 0;
            _WBFSSize = 0;
            _WiiSectorUsageTable = null;

            if(_Drive.IsReady) return; //Se o windows conhece o FS do disco então não é um disco de Wii

            DVDRomReader reader = null;
            WiiDisc disc = null;

            try
            {

                reader = new DVDRomReader(Name[0]);
                if (reader.Result != 0)
                {
                    _WiiDiscInserted = false;
                    return;
                }

                if (reader.Lock() != IORet.RET_IO_OK)
                {
                    reader.Close();
                    return;
                }

                disc = new WiiDisc(reader, false);
                disc.Open();

                if (disc.BuildDisc(DiscBuildMode) == 0)
                {
                    _Name = disc.name;
                    _Code = disc.code;
                    _WBFSSize = (long)disc.UsedSectors * WBFSDevice.wiiSectorSize;
                    _Size = reader.Length;

                    _WiiSectorUsageTable = new byte[WBFSDevice.wiiSectorsPerDisc];
                    disc.SectorUsageTable.CopyTo(_WiiSectorUsageTable, 0);

                    _WiiDiscInserted = true;
                }
            }
            catch
            {
                _WiiDiscInserted = false;
                _Code = "";
                _Name = "";
                _Size = 0;
                _WBFSSize = 0;
                _WiiSectorUsageTable = null;
            }

            if (disc != null) { disc.Close(); disc = null; }
            if (reader != null) { reader.Close(); reader = null; }
        }
    }
}
